package com.faithbj.controller.compare;

import com.faithbj.common.configuration.Pager;
import com.faithbj.common.model.CheckTotal;
import com.faithbj.common.model.DataExportLog;
import com.faithbj.common.model.Dictionary;
import com.faithbj.common.model.User;
import com.faithbj.common.model.fm.FamilyMember;
import com.faithbj.common.model.fm.verify.FamilyMemberVerify;
import com.faithbj.common.utils.DateUtils;
import com.faithbj.common.utils.DictionaryUtil;
import com.faithbj.common.web.controller.BaseController;
import com.faithbj.process.ProcessApplicationService;
import com.faithbj.process.State;
import com.faithbj.process.TaskModel;
import com.faithbj.process.stats.VerifyReason;
import com.faithbj.service.CheckTotalService;
import com.faithbj.service.CompareService;
import com.faithbj.service.FamilyMemberVerifyService;
import com.faithbj.support.compare.AjaxResult;
import com.faithbj.support.updownload.FileUploadHandler;
import com.faithbj.support.updownload.FileUploadHandlerSaveToLocalDisk;
import com.faithbj.support.vo.CompareRequest;
import com.faithbj.utils.SystemConfigUtil;
import com.faithbj.webservice.WebServiceClient;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;


/**
 * 准入标准比对核实Controller，
 * <p>
 * 目前有文件上传、文件下载和手动批次生成三个method
 * </p>
 * 后续根据业务需求可以做拆分
 * 
 * @author chen liu
 */
@SuppressWarnings("unchecked")
@Controller
public class CompareController extends BaseController {

    /**
	 * 
	 */
    private static final long serialVersionUID = 3502990015134594157L;

	@Resource
	private FileUploadHandler uploadHandler;
	
	@Resource
	private CheckTotalService ctService;
	
	@Resource
	private CompareService compareService;
	
	@Resource
	private DictionaryUtil dictionaryUtil;
	@Resource
	private SystemConfigUtil systemConfigUtil;
	
	@Resource
	private ProcessApplicationService processApplicationService;
	@Resource
	private FamilyMemberVerifyService familyMemberVerifyService;
		
    /**
     * 显示基本信息比对首页
     */
    @RequestMapping(value = "/admissionverify/index")
    public String list(Pager pager, ModelMap map) {
		List<TaskModel> tasks = processApplicationService
				.listAvailableTasksWithContentByUserAndState(State.COMPARISON,
						pager.getFirstResult(), pager.getPageSize());
		pager.setResult(tasks);
		pager.setTotalCount(processApplicationService.countAvailableTasksByUserAndState(State.COMPARISON));
		map.put("pager", pager);
        return "/admissionverify/index";
    }

    /**
     * 显示基本信息比对首页
     */
    @RequestMapping(value = "/admissionverify/{id}/{taskId}/{result}")
    public String show(@PathVariable("id") String id,@PathVariable("taskId") Long taskId,@PathVariable("result") Boolean result,ModelMap map) {
    	
//    	if (!result)
//			processApplicationService.claimAndGroupStartTask(taskId); // not needed since tasks are now assigned in order.
    	
    	CheckTotal checkTotal = ctService.getCheckTotalById(id);
		Set<FamilyMember> members = checkTotal.getFamilyMembers();
		
		List<FamilyMember> fmlist= new ArrayList<FamilyMember>(members );
		
		for (FamilyMember fm : fmlist) {
			if (fm.getMainApplicant()) {
				FamilyMember tfm=fmlist.get(0);
				fmlist.set(0, fm);
				fm=tfm;
			}
		}
		
		map.put("fm", fmlist);
		
		
		List<Dictionary> idTypes = dictionaryUtil.getListByTypeName("证件类型");
		List<Dictionary> education = dictionaryUtil.getListByTypeName("文化程度");
		List<Dictionary> maritalStatusList = dictionaryUtil
				.getListByTypeName("婚姻状况");
		List<Dictionary> householdTypeList = dictionaryUtil
				.getListByTypeName("户籍类型");

		map.put("educations", education);
		map.put("maritalStatusList", maritalStatusList);
		map.put("idTypes", idTypes);
		map.put("householdTypes", householdTypeList);

		map.put("checkTotal", checkTotal);
 
        return "/admissionverify/infoShow";
    }
    
    
	/**
	 * 保存基本信息比对核定值
	 * 家庭成员基本情况核定表
	 */
	@RequestMapping(value = "/admissionverify/savecheck", method = RequestMethod.POST)
    @ResponseBody
	public ModelMap savecheck(FamilyMemberVerify entity) {
		ModelMap map= new ModelMap();
		familyMemberVerifyService.save(entity);
		map.put("status", "1");//保存成功
		return map;
	}
	
	/**
	 * 基本信息比对意见
	 */
	@RequestMapping(value = "/admissionverify/sendCheck", method = RequestMethod.POST)
	@ResponseBody
	public ModelMap sendCheck(VerifyReason verifyReason, String checkTotalId,	Long taskId) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("verifyResult", verifyReason.getId());
        if (verifyReason == VerifyReason.EXIST_DIFFERENCE) {
            map.put("pauseReason", "测试中止原因"); // TODO xiongyuanwei 这里需要真正的pauseReason
        } else {
            map.put("pauseReason", "无");
        }
		CheckTotal checkTotal = ctService.getCheckTotalById(checkTotalId);
        if (checkTotal == null) { // TODO xiongyuanwei checktotal 应当不是null，若能保证这一点则去掉这个if
            TaskModel t = processApplicationService.getTaskWithContent(taskId);
            checkTotal = t.getCheckTotal();
        }
		processApplicationService.completeTask(taskId, checkTotal, map);
		ModelMap mMap=new ModelMap();
		mMap.put("status", "1");//跳转到基本信息页
		
		return mMap;
	}
	
	

    /**
     * 导出数据文件(data.zip)
     */
    @RequestMapping("/compare/exportDBFile")
    public void exportDBFile(HttpServletRequest request, HttpServletResponse response) {
        // 获取用户进行权限验证？？如何验证
        User user = super.getLoginUser();
        if(user == null){
            return;
        }

        // 查询数据导出记录表，获取本区域最近一次导出的时间
        Date latestExportTime = compareService.getLatestExportTime();
        if(latestExportTime == null){
            latestExportTime = DateUtils.getStringToDate("1970-01-01 00:00:00", DateUtils.DateFormatDefault);
        }
        System.out.println(latestExportTime);
        
        // 调用脚本执行数据导出和压缩打包（传入regionId,文件名(时间戳),上次导出时间）
        // ExecUtil.execute(workingDirPath, command, args, timeout);

        // 获取文件路径
        String dataZipFilePath = getDataFilePath();

        // 执行文件下载
        String fileDisplayName = "exportData.zip";
        response.reset();
        response.setContentType("application/zip");
        response.addHeader("Content-Disposition", "attachment;filename=" + fileDisplayName);

        OutputStream output = null;
        FileInputStream input = null;
        try {
            output = response.getOutputStream();
            input = new FileInputStream(dataZipFilePath);
            byte[] b = new byte[1024];
            int i = 0;
            while ((i = input.read(b)) > 0) {
                output.write(b, 0, i);
            }
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
        // 写入数据导出记录表
        DataExportLog exportLog = new DataExportLog();
        exportLog.setUserId(user.getId());
        compareService.saveOrUpdateExportLog(exportLog);
    }

    /**
     * 导入数据文件,先导入到临时文件/dana/tmp/im.zip,然后解压拷贝到目标目录/home/scanfiles,tmp文件清空
     */
    @RequestMapping(value="/compare/importDBFile",method=RequestMethod.POST)
    @ResponseBody
    public AjaxResult importDBFile(MultipartFile dbData) {
        AjaxResult result = new AjaxResult(true);
        Map<Integer, String> checkResult=uploadHandler.checkFileExtention(dbData);
         
        for (Integer relt : checkResult.keySet()){    
            if(!FileUploadHandlerSaveToLocalDisk.UPLOAD_PERMITION.equals(relt))
            {//说明验证没通过，返回
            	result.setResult(false);
                result.addMsg(checkResult.get(relt));
            }
        }  
 
        uploadHandler.uploadByFilePath(dbData, systemConfigUtil.getImportTmpDir());
        
        //TODO runtime unzip
        
        result.setResult(true);
        return result;
    }

    /**
     * 人工生成批次
     * 
     * @param request
     * @param acceptNums 受理编号数组
     * @param model
     * @return
     */
    @RequestMapping("/compare/generateBatch")
    @ResponseBody
    public AjaxResult generateBatch(HttpServletRequest request, String[] acceptNums, ModelMap model) {
        AjaxResult result = new AjaxResult(true);

        // 参数验证
        if (acceptNums == null || acceptNums.length == 0) {
            result.setResult(false);
            result.addMsg("受理编号不合法，请确认!");
        }

        // 获取用户进行权限验证？？如何验证
        User user = super.getLoginUser();

        // 根据受理编号查询核对总体情况记录
        Map<String, List<CheckTotal>> batchingMap = ctService.getCheckTotalMapForBatching(acceptNums);

        // 生成批次,发送委办
        Object resultObj = compareService.genearateBatch(batchingMap);
        if (resultObj != null && !(resultObj instanceof String)) {
            Map<String, Map<String, List<CompareRequest>>> resultMap = (Map<String, Map<String, List<CompareRequest>>>) resultObj;
            System.out.println("fullCompareReqMap size is : " + resultMap.keySet().size());
            for (String regionId : resultMap.keySet()) {
                for (String depNum : resultMap.get(regionId).keySet()) {
                    WebServiceClient.returnOfficalData(depNum, resultMap.get(regionId).get(depNum));
                }
            }
        } else {
            result.setResult(false);
            result.addMsg((String) resultObj);
        }

        return result;
    }

    private String getDataFilePath() {
        return "F:\\data.zip";
    }
}
